iT邦幫忙

2022 iThome 鐵人賽

DAY 21
2
Modern Web

今天我想來在 Angular 應用程式上加上測試保護系列 第 21

Day 21 - 端對端測試 - 利用 Cypress 驗證應用程式

  • 分享至 

  • xImage
  •  

前言

如昨天文章所言,我們可以利用 Cypress 所提供的預設斷言來驗證應用程式執行的狀況。這一篇則來說明如何利用 Cypress 的 should() 方法驗證應用程式。

利用 should() 驗證應用程式

.should(chainers)
.should(chainers, value)
.should(chainers, method, value)
.should(callbackFn)

在 Cypress 的 should() 方法中,整合了 Chai、Chai-jQuery 與 Sinon-Chai 函式庫裡的斷言,來驗證應用程式執行的過程是否符合預期,常用的有:

驗證文字資料是否正確

當我們取得頁面元素的內容文字時,我們可以利用 eq 來與預期值進行相等的比較,例如,在 application.cy.ts 裡,針對瀏覽器標題文字的驗證,就可以寫成:

it('顯示瀏覽器標題為 "2022 鐵人賽範例"', () => {
  cy.title().should('eq', '2022 鐵人賽範例');
});

若要針對部份文字的驗證,則會使用 include 來進行。例如,在測試點選登入按鈕時,是否正確載入頁面,就可以驗證是否包含特定文字:

it('當點選登入按鈕, 應轉至登入頁面', () => {
  cy.url().should('include', '/login');
});

順帶一提,如果需要針對物件進行驗證可以使用斷言之前加入 deep,如 deep.eqdeep.include

驗證目標元素應被停用

如果我們要驗證在登入頁面中,當輸入的帳號不存在的時候,登入按鈕應被停用,就可以透過 be.disabled 來針對登入按鈕的停用狀態進行驗證。

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.get('button').contains('登入').parent().should('be.disabled');
});

驗證 CSS 樣式設定

實務上,常會需要在特定操作下,更換特定頁面元素的樣式。在撰寫 Cypress 端對端測試時,就可以利用 have.class 來驗證目標元素是否套件所預期的樣式。

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.get('button')
    .contains('登入')
    .parent()
    .should('have.class', 'mat-button-disabled');
});

在上面程式中,因為 Angular Material 在被停用的按鈕套用上 mat-button-disabled 樣式,所以我們也可以驗證登入按鈕是否有套用此樣式。

驗證頁面元素是否存在

同樣地,使用「帳號不存在」的測試案例,此時會需要出現對應的錯誤訊息,此時就會使用 exist 斷言來檢查錯誤訊息的頁面元素是否存在。

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.contains('此帳號不存在').should('exist');
});

驗證頁面元素內容顯示是否正確

除了上面驗證錯誤訊息是否存在之外,我們也可以利用 have.text 斷言來確認 MatError 頁面元素的文字內容是否為「此帳號不存在」。

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.get('mat-error').should('have.text', '此帳號不存在');
});

除此之外,也可以利用 include.textcontain 來檢查文字內容是否包含預期文字;更進一步,還可以利用 match 斷言來透過正規化字串驗證文字內容。

反向驗證

上面的斷言都是以正向的方式來做驗證,當需要做反向驗證的時候,如不存在、不包含等,可以在正向驗證前加入 not 即可;例如,我們要驗證登入按鈕是啟用,就可以寫成:

cy.get('button').contains('登入').parent().should('not.be.disabled');

頁面元素的連續驗證

有時候我們會需要針對同一個頁面元素進行多個不同的驗證,這時候就可以利用 Cypress 提供的 and() 來把要驗證的事項串連在一起。例如在「帳號不存在」的測試案例,我們可以在檢查錯誤訊息內容前,先確認 MatError 是否存在,那就可以寫成:

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.get('mat-error').should('exist').and('have.text', '此帳號不存在');
});

利用 expect 驗證應用程式

從一開始的 should() 方法簽章中可以看到,其也接收傳入一個方法,我們可以透過這個方法來針對目標元素,進行多種不同的驗證。

it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
  cy.get('button.mat-icon-button').contains('login').click();
  cy.get('input[type=text]').type('userB').blur();
  cy.get('mat-error').should((target) => {
    expect(target).to.exist;
    expect(target).to.have.text('此帳號不存在');
  });
});

如上面程式,在傳入的方法中,會使用 expect() 方法來針對頁面進行是否存在與錯誤訊息文字的驗證。

接下來

今天介紹了在 Cypress 驗證的撰寫方式,完整的測試程式可以參考 GitHub。接下來,會來說明 Cypress 提供的 Fixture 來組織測試案例資料,以及如何設定環境變數。


上一篇
Day 20 - 端對端測試 - 利用 Cypress 描述使用者操作
下一篇
Day 22 - 端對端測試 - 使用 Fixture 定義測試資料與環境變數設定
系列文
今天我想來在 Angular 應用程式上加上測試保護30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言